<?php
namespace haibao\cms\data;

use \haibao\frame\data\query\Condition;
use \haibao\cms\model\filter\ProductCategoryDefine as ProductCategoryFilter;
use \haibao\cms\model\data\ProductCategoryDefine as ProductCategoryModel;

class ProductCategoryDefine extends \haibao\cms\data\BaseMysql{
	
	private static $cacheCategoryDictName = 'CategroyDict';
	private static $cacheCategoryTreeName = 'CategoryTree';
	
	
	public function __construct(){
		parent::__construct('\haibao\cms\model\data\ProductCategoryDefine');
	}
	
	/**
	 * 获取分类树形结构
	 * @return array
	 */
	public function getCategoryTree(){
		$categoryTreeCache = $this->getCache(self::$cacheCategoryTreeName);
		return $categoryTreeCache ? $categoryTreeCache : $this->setCategoryTree();
	}
	
	/**
	 * 设置分类树形
	 * @param $return Boolean 是否需要返回值
	 */
	private function setCategoryTree($return = true){
		$categoryTree = array();
		$categorysDict = $this->getAllCategorysDict();
		if($categorysDict){
			foreach($categorysDict as $categoryDict){
				if(isset($categorysDict[$categoryDict[ProductCategoryFilter::CONDITION_FIELD_NAME_PARENTID]])){
					$categorysDict[$categoryDict[ProductCategoryFilter::CONDITION_FIELD_NAME_PARENTID]]['children'][] = &$categorysDict[$categoryDict[ProductCategoryFilter::CONDITION_FIELD_NAME_ID]];
				}else{
					$categoryTree[$categoryDict[ProductCategoryFilter::CONDITION_FIELD_NAME_ID]] = &$categorysDict[$categoryDict[ProductCategoryFilter::CONDITION_FIELD_NAME_ID]];
				}
			}
		}
		$categoryTree && $this->setCache(self::$cacheCategoryTreeName, $categoryTree);
		if($return){
			return $categoryTree;
		}
	}
	/**
	 * 获取没有父子关系的分类详情
	 */
	public function getAllCategorysDict(){
		$categorysDictCache = $this->getCache(self::$cacheCategoryDictName);
		return $categorysDictCache ? $categorysDictCache : $this->setAllCategorysDict();
	}
	
	/**
	 * 将全部可用的产品分类放入缓存中
	 * @param $return Boolean 是否需要返回值
	 */
	private function setAllCategorysDict($return = true){
		$productCategoryFilter = new ProductCategoryFilter();
		
// 		$productCategoryFilter->select(array(
// 				ProductCategoryFilter::CONDITION_FIELD_NAME_ID,
// 				ProductCategoryFilter::CONDITION_FIELD_NAME_CATEGORY_NAME,
// 				ProductCategoryFilter::CONDITION_FIELD_NAEM_ORDERNO,
// 				ProductCategoryFilter::CONDITION_FIELD_NAME_PARENTID
// 				));
		$productCategoryFilter->order(ProductCategoryFilter::CONDITION_FIELD_NAEM_ORDERNO);
		$productCategoryFilter->where(ProductCategoryFilter::CONDITION_FIELD_NAME_STATUS, Condition::CONDITION_EQUAL, ProductCategoryModel::STATUS_ENABLE);
		$categorysDict = $this->getAll($productCategoryFilter);
		
		$categorysArr = array();
		if($categorysDict){
			foreach($categorysDict as  $key=>$categoryModel){
				$categorysArr[$categoryModel->Id] = $categoryModel->toArray();
			}	
		}
		if($categorysArr){
			$this->setCache(self::$cacheCategoryDictName, $categorysArr);
		}
		if($return){
			return $categorysArr;
		}
	}
	
	/**
	 * 通过分类id查找
	 */
	public function getCategoryById($categoryId){
		return parent::getOneById($categoryId);
	}
	
	/**
	 * @param $productCategoryFilter \haibao\cms\model\filter\ProductCategoryDefine
	 */
	public function getAll($productCategoryFilter){
		return parent::getAll($productCategoryFilter);
	}
	
	/**
	 * 获取当前层级最大的排序
	 */
	public function getMaxOrderByParentId($parentId){
		$max = null;
		$sql = "select max(OrderNo) as max from ProductCategoryDefine where ParentId=%s AND Status = %s";
		$result  = $this->query($sql,array(
				$parentId,\haibao\cms\model\data\ProductCategoryDefine::STATUS_ENABLE
				));
		
		while ($result->fetch_assoc()){
			$max = $result->getData('max');
		}
		return $max;
	}
	
	/**
	 * 添加产品分类
	 * @param \haibao\cms\model\data\ProductCategoryDefine $model
	 */
	public function add($productCategoryModel){
		self::beginTranscation();
		try{
			parent::add($productCategoryModel);
				$sql = 'insert into ProductCategoryMap(CategoryId, ParentId)
				select CategoryId, ParentId from (
				(select %s as CategoryId, ParentId from ProductCategoryMap where CategoryId = %s and ParentId !=0)
				union
				(select %s,%s from ProductCategoryMap limit 1)
				) a';
				$this->query($sql, array(
						$productCategoryModel->Id, $productCategoryModel->ParentId, $productCategoryModel->Id, $productCategoryModel->Id,
				));
		
			$this->unsetCache(self::$cacheCategoryTreeName);
			$this->unsetCache(self::$cacheCategoryDictName);
			if(\haibao\classlibrary\cms\Config::getConfig(\haibao\classlibrary\cms\Config::SYNC_OLD)){
				$oldId = $this->addOldCategory($productCategoryModel);
				$this->addDataMigrationMap($productCategoryModel,$oldId);
			}
		}catch (\Exception $e){
			$this->rollback();
			throw $e;
		}
		$this->endTranscation();
		return $productCategoryModel->Id;
	}
	
	private function addDataMigrationMap($model,$oldPrimaryKey){
		$this->setConfig( \haibao\classlibrary\cms\Config::CLASSLIBRARY_CONFIG_MYSQL_HAIBAO_CMS );
		
		$tableName = $model->getTableName();
		$sql = "insert into `DataMigrationMap`(`TableName`,`PrimaryKey`,`OldPrimaryKey`)values(%s,%s,%s)";
		$this->query($sql,array($tableName,$model->Id,$oldPrimaryKey));
		
	}
	
	private function deleteDataMigrationMap($model){
		$this->setConfig( \haibao\classlibrary\cms\Config::CLASSLIBRARY_CONFIG_MYSQL_HAIBAO_CMS );
	
		$tableName = $model->getTableName();
		$sql = "delete from `DataMigrationMap` where `TableName`= %s AND `PrimaryKey`=%s";
		$this->query($sql,array($tableName,$model->Id));
	
	}
	
	private function addOldCategory($model){
		$this->setConfig( \haibao\classlibrary\cms\Config::CLASSLIBRARY_CONFIG_MYSQL_HAIBAO_ARTICLE );
		
		$sql = "insert into `brand_category` (`cate_name`, `top_cateid`, `parent_cateid`, `level`, `cate_status`) values(%s, %s, %s, %s, %s)";
		$oldKey = $this->getDataMigration($model->getTableName(), $model->ParentId);
		$oldCategoryInfo = $this->getOldCategory($oldKey);
		if(!$oldCategoryInfo){
			$oldCategoryInfo['level'] = 0;
			$oldCategoryInfo['cateid'] = 0;
		}
		$this->query($sql, array(
				$model->CategoryName, 0, $oldCategoryInfo['cateid'],$oldCategoryInfo['level'] + 1, 1
		));
		return $this->getDb()->insert_id;
	}
	
	private function getOldCategory($id){
		$this->setConfig( \haibao\classlibrary\cms\Config::CLASSLIBRARY_CONFIG_MYSQL_HAIBAO_ARTICLE );
		
		$sql = "select `cateid`,`parent_cateid`,`level` from `brand_category` where `cateid` = %s";
		$result = $this->query($sql,array($id));
		$arrSet = array();
		while($result->fetch_assoc()){
			$arrSet['cateid'] = $result->getData('cateid');
			$arrSet['parentId'] = $result->getData('parent_cateid');
			$arrSet['level'] = $result->getData('level');
			$arrSet['cateid'] = $result->getData('cateid');
		}
		return $arrSet;
	}
	
	/**
	 * 保存产品分类
	 * @param \haibao\cms\model\data\ProductCategoryDefine $model
	 */
	public function save($model){
		$arrSet = array();
		$arrSet[ProductCategoryFilter::CONDITION_FIELD_NAME_CATEGORY_NAME] = $model->CategoryName;
		$arrSet[ProductCategoryFilter::CONDITION_FIELD_NAEM_ORDERNO] = $model->OrderNo;
		$arrSet[ProductCategoryFilter::CONDITION_FIELD_NAME_PARENTID] = $model->ParentId;
		self::beginTranscation();
		try{
			parent::updateById($model->Id, $arrSet);
				$sql = 'delete from ProductCategoryMap where Id in (
						select Id from
							(
								select map.Id from ProductCategoryMap map inner join (
									select * from
									(
										select a.ParentId from ProductCategoryMap a where a.CategoryId = %s and a.ParentId <> %s
									) a
									join
									(
										select b.CategoryId from ProductCategoryMap b where b.ParentId = %s
									) b
								) tmp ON map.ParentId = tmp.ParentId and map.CategoryId = tmp.CategoryId
							) a
						)';
			$this->query($sql, array_pad(array(), 3, $model->Id));
				
			$sql = 'insert into ProductCategoryMap (CategoryId, ParentId) select b.CategoryId,a.ParentId from
						(
							select ParentId from ProductCategoryMap where CategoryId = %s
						) a join (
							select CategoryId from ProductCategoryMap where ParentId = %s
						) b';
			$this->query($sql, array($model->ParentId, $model->Id));
			$this->unsetCache(self::$cacheCategoryTreeName);
			$this->unsetCache(self::$cacheCategoryDictName);
		
		}catch (\Exception $e){
			$this->rollback();
 			throw $e;
 		}
		$this->endTranscation();
		if(\haibao\classlibrary\cms\Config::getConfig(\haibao\classlibrary\cms\Config::SYNC_OLD)){
			$this->updateOldCategory($model);
		}
	}
	/**
	 * 删除分类
	 * @param $categoryId
	 */
	public function delete($categoryId){
		self::beginTranscation();
		try{
			parent::updateById($categoryId, array('Status'=>\haibao\cms\model\data\ProductCategoryDefine::STATUS_DISABLE));
			$this->unsetCache(self::$cacheCategoryTreeName);
			$this->unsetCache(self::$cacheCategoryDictName);
			
		}catch (\Exception $e){
			$this->rollback();
			throw $e;
		}
		$this->endTranscation();
		if(\haibao\classlibrary\cms\Config::getConfig(\haibao\classlibrary\cms\Config::SYNC_OLD)){
			$model = $this->getCategoryById($categoryId);
			$this->deleteOldCategory($model);
			//$this->deleteDataMigrationMap($model);
		}
	}
	/**
	 * 查找所有孩子节点
	 */
	public function getAllChildrenCategory($categoryId,$categoryAllDict = null){
		static $childArr = array();
		if(!$categoryAllDict){
			$categoryAllDict = $this->getAllCategorysDict();
		}
		foreach($categoryAllDict as $key=>$dict){
			if($dict[ProductCategoryFilter::CONDITION_FIELD_NAME_PARENTID] == $categoryId){
				array_push($childArr, $dict);
				$childArr = $this->getAllChildrenCategory($dict[ProductCategoryFilter::CONDITION_FIELD_NAME_ID] ,$categoryAllDict);
			}
		}
		return $childArr;
	}
	
	public function getParentCategoryId($categoryId){
		$parentCategoryId = 0;
		$categoryAllDict = $this->getAllCategorysDict();
		foreach($categoryAllDict as $key=>$dict){
			if($dict[ProductCategoryFilter::CONDITION_FIELD_NAME_ID] == $categoryId){
				$parentCategoryId = $dict[ProductCategoryFilter::CONDITION_FIELD_NAME_PARENTID];
				break;
			}
		}
		return $parentCategoryId;
	}
	
	/**
	 * 查询下级分类
	 * @param int $parentId
	 */
	public function getChildCategory($parentId){
		$childArr = array();
		$categoryAllDict = $this->getAllCategorysDict();
		foreach($categoryAllDict as $key=>$dict){
			if($dict[ProductCategoryFilter::CONDITION_FIELD_NAME_PARENTID] == $parentId){
				array_push($childArr, $dict);
			}
		}
		return $childArr;
	}
	
	/**
	 * \haibao\cms\model\filter\ProductCategoryFilter $categoryFilter;
	 */
	public function getCategoryByFilter($categoryFilter){
		return parent::getAll($categoryFilter);
	}
	
	/**
	 * 
	 * @param string $tableName
	 * @param int $newPrimaryKey
	 */
	private function getDataMigration($tableName,$newPrimaryKey){
		$this->setConfig( \haibao\classlibrary\cms\Config::CLASSLIBRARY_CONFIG_MYSQL_HAIBAO_CMS );
		
		$sql  ="select `PrimaryKey`,`OldPrimaryKey` from DataMigrationMap where TableName=%s and PrimaryKey =%s";
		$result = $this->query($sql,array(
				$tableName,$newPrimaryKey
				));
		$oldPrimaryKey = null;
		while ($result->fetch_assoc()){
			$oldPrimaryKey = $result->getData('OldPrimaryKey');
		}
		return $oldPrimaryKey;
	}
	
	private function updateOldCategory($model){
		$tableName = $model->getTableName();
		$oldId =  $this->getDataMigration($tableName,$model->Id);
		$oldParentId = $this->getDataMigration($tableName,$model->ParentId);
		if($oldId && $oldParentId){
			$this->setConfig( \haibao\classlibrary\cms\Config::CLASSLIBRARY_CONFIG_MYSQL_HAIBAO_ARTICLE );
			if($model->ParentId){
				$oldCategoryInfo = $this->getOldCategory($oldParentId);
			}else{
				$oldCategoryInfo['level'] = 0;
			}
			$sql = "update  `brand_category` set `cate_name` = %s,`parent_cateid` = %s,`level` = %s where `cateid` = %s";
		  	$this->query($sql,array($model->CategoryName,$oldParentId,$oldCategoryInfo['level'] + 1,$oldId));
		}
	}
	
	public function deleteOldCategory($model){
		$this->setConfig( \haibao\classlibrary\cms\Config::CLASSLIBRARY_CONFIG_MYSQL_HAIBAO_ARTICLE );
		
		$tableName = $model->getTableName();
		$oldId =  $this->getDataMigration($tableName,$model->Id);
		if($oldId){
			$this->setConfig( \haibao\classlibrary\cms\Config::CLASSLIBRARY_CONFIG_MYSQL_HAIBAO_ARTICLE );
			$sql = "update  `brand_category` set `cate_status` = %s where `cateid` = %s";
			$this->query($sql,array(0,$oldId));
		}
	}
}
